package bd;

import java.util.Date;
import java.util.Iterator;
import java.util.List;

import negocios.CaixaPostal;
import negocios.Convite;
import negocios.Localizador;
import negocios.LocalizadorIP;
import negocios.LocalizadorManual;
import negocios.Mensagem;
import negocios.MensagemTexto;
import negocios.Relacionamento;
import negocios.SMS;
import negocios.Usuario;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Text;

/**
 * Classe que gera elementos para o banco de dados XML a partir de objetos do
 * pacote de negocios.
 * 
 * @author Jonathan Brilhante
 * @author Jose Rafael
 * @author Nata Venancio
 * @author Renato Almeida
 * 
 * @version 2.0
 */

public class GeraElementosXML {
	static final String CONVITE = Convite.class.getName();
	static final String SMS = SMS.class.getName();
	static final String MENSAGEM_TEXTO = MensagemTexto.class.getName();
	static final String MANUAL = LocalizadorManual.class.getName();
	static final String IP = LocalizadorIP.class.getName();

	private Document doc;

	public GeraElementosXML(Document doc) {
		this.doc = doc;
	}

	/**
	 * Seta um objeto do tipo Doc.
	 * 
	 * @param doc
	 */
	public void setDoc(Document doc) {
		this.doc = doc;
	}

	/**
	 * Retorna um simples elemento para o documento XML.
	 * 
	 * @param nomeElemento
	 *            o nome do elemento
	 * @param texto
	 *            descricao do elemento.
	 * @return o elemento generico
	 */
	private Element elementoGenerico(String nomeElemento, String texto) {
		Element elementoGenerico = doc.createElement(nomeElemento);
		Text valorElementoGenerico = doc.createTextNode(texto);
		elementoGenerico.appendChild(valorElementoGenerico);
		return elementoGenerico;
	}

	/**
	 * Cria um elemento Relacionamento para ser armazenado no arquivo XML.
	 * 
	 * @param amigo
	 *            o relacionamento
	 * @return o elemento
	 */
	private Element criarElementoAmigo(Relacionamento amigo) {
		Element elementoAmigo = doc.createElement("amigo");
		elementoAmigo.setAttribute("ocultar", amigo.isOculto() + "");
		Element elementoUsername = elementoGenerico("username", amigo
				.getAmigo().getLogin());
		Element meuUsername = elementoGenerico("meuusername", amigo.getLogin());
		elementoAmigo.appendChild(elementoUsername);
		elementoAmigo.appendChild(meuUsername);
		return elementoAmigo;
	}

	/**
	 * Cria um elemento a partir de um objeto Data.
	 * 
	 * @param data
	 *            a data
	 * @return o elemento
	 */
	@SuppressWarnings("deprecation")
	private Element criarElementoData(Date data) {
		Element elementoUsuario = doc.createElement("data");
		elementoUsuario.setAttribute("dia", data.getDate() + "");
		elementoUsuario.setAttribute("mes", data.getMonth() + "");
		elementoUsuario.setAttribute("ano", data.getYear() + "");
		return elementoUsuario;
	}

	/**
	 * Cria um elemento a partir de um objeto Mensagem.
	 * 
	 * @param mensagem
	 *            a mensagem
	 * @return o elemento
	 */
	private Element criarElementoMensagem(Mensagem mensagem) {
		Element elementoUsuario = doc.createElement("mensagem");
		elementoUsuario.setAttribute("estado", mensagem.isLida() + "");
		elementoUsuario.setAttribute("tipo", mensagem.getClass().toString());
		Element remetente = elementoGenerico("remetente", mensagem
				.getRemetente());
		Element destinatario = elementoGenerico("destinatario", mensagem
				.getDestinatario());
		Element assunto = elementoGenerico("assunto", mensagem.getAssunto());
		Element data = criarElementoData(mensagem.getDataEnvio());
		Element conteudo = elementoGenerico("conteudo", mensagem.getConteudo());
		elementoUsuario.appendChild(remetente);
		elementoUsuario.appendChild(destinatario);
		if (mensagem.getClass().toString().endsWith(CONVITE)) {
			Element email = elementoGenerico("email", ((Convite) mensagem)
					.getEmailRemetente());
			elementoUsuario.appendChild(email);
		}
		if (!mensagem.getClass().toString().endsWith(CONVITE)) {
			elementoUsuario.appendChild(assunto);
			elementoUsuario.appendChild(conteudo);
		}
		elementoUsuario.appendChild(data);
		return elementoUsuario;
	}

	/**
	 * 
	 * Cria um elemento a partir de um objeto CaixaPostal.
	 * 
	 * @param caixa
	 *            a caixa postal
	 * @return o elemento
	 */
	private Element criarElementoCaixaPostal(CaixaPostal caixa) {
		Element elementoCaixaPostal = doc.createElement("caixapostal");
		Element elementoMensagens = elementoGenerico("mensagens", "Mensagens");
		Iterator<Mensagem> iterator = caixa.iterator();
		while (iterator.hasNext()) {
			Element elementoMensagem = criarElementoMensagem(iterator.next());
			elementoMensagens.appendChild(elementoMensagem);
		}
		elementoCaixaPostal.appendChild(elementoMensagens);
		return elementoCaixaPostal;
	}

	/**
	 * Cria um elemento a partir de um objeto Localizador.
	 * 
	 * @param localizador
	 *            a localizador
	 * @return o elemento
	 */
	private Element criaElementoLocalizador(Localizador localizador) {
		String classe = localizador.getClass().getName();
		Element elementoLocalizador = doc.createElement("localizador");
		elementoLocalizador.appendChild(elementoGenerico("tipo", classe));
		if (classe.endsWith(IP)) {
			LocalizadorIP loc = (LocalizadorIP) localizador;
			Element ip = elementoGenerico("ip", loc.getIp());
			elementoLocalizador.appendChild(ip);
		} else if (classe.endsWith(MANUAL)) {
			LocalizadorManual loc = (LocalizadorManual) localizador;
			Element latitude = elementoGenerico("latitude", loc.getLatitude()
					+ "");
			Element longitude = elementoGenerico("longitude", loc
					.getLongitude()
					+ "");
			elementoLocalizador.appendChild(latitude);
			elementoLocalizador.appendChild(longitude);
		}
		return elementoLocalizador;
	}

	/**
	 * Cria um elemento a partir de um objeto Usuario.
	 * 
	 * @param usuario
	 *            o usuario
	 * @return o elemento
	 */
	public Element criarElementoUsuario(Usuario usuario) {
		Element elementoUsuario = doc.createElement("usuario");
		elementoUsuario.setAttribute("username", usuario.getLogin());
		elementoUsuario.setAttribute("senha", usuario.getSenha());
		Element nome = elementoGenerico("nome", usuario.getNome());
		Element email = elementoGenerico("email", usuario.getEmail());
		Element telefone = elementoGenerico("telefone", usuario.getTelefone());
		Element listaAmigos = criarElementoListaAmigos(usuario.amigos());
		Element localidade;
		localidade = criaElementoLocalizador(usuario.getLocalizador());
		Element caixaPostal = criarElementoCaixaPostal(usuario.getCaixaPostal());
		elementoUsuario.appendChild(email);
		elementoUsuario.appendChild(nome);
		elementoUsuario.appendChild(telefone);
		elementoUsuario.appendChild(listaAmigos);
		elementoUsuario.appendChild(localidade);
		elementoUsuario.appendChild(caixaPostal);
		return elementoUsuario;
	}

	/**
	 * Cria um elemento Relacionamento, que serve para armazenar os objetos
	 * Relacinoamento (do Usuario) no arquivo XML.
	 * 
	 * @param amigos
	 *            a lista de relacionamentos do usuario
	 * @return o elemento
	 */
	private Element criarElementoListaAmigos(List<Relacionamento> amigos) {
		Element amigosAux = doc.createElement("amigos");
		for (Relacionamento a : amigos) {
			amigosAux.appendChild(criarElementoAmigo(a));
		}
		return amigosAux;
	}
}